#include "8bit.h"
#include "cp1252cvt.h"

using namespace std;


static const wchar_t cp2ucs[] = {
	0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
	0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017D, 0x0000,
	0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
	0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x017E, 0x0178,
	0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
	0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
	0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
	0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
	0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
	0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
	0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
	0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
	0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
	0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
	0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
	0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
};

static const struct cw ucs2cp[] = {
	{0xA0, 0x00A0}, {0xA1, 0x00A1}, {0xA2, 0x00A2}, {0xA3, 0x00A3},
	{0xA4, 0x00A4}, {0xA5, 0x00A5}, {0xA6, 0x00A6}, {0xA7, 0x00A7},
	{0xA8, 0x00A8}, {0xA9, 0x00A9}, {0xAA, 0x00AA}, {0xAB, 0x00AB},
	{0xAC, 0x00AC}, {0xAD, 0x00AD}, {0xAE, 0x00AE}, {0xAF, 0x00AF},
	{0xB0, 0x00B0}, {0xB1, 0x00B1}, {0xB2, 0x00B2}, {0xB3, 0x00B3},
	{0xB4, 0x00B4}, {0xB5, 0x00B5}, {0xB6, 0x00B6}, {0xB7, 0x00B7},
	{0xB8, 0x00B8}, {0xB9, 0x00B9}, {0xBA, 0x00BA}, {0xBB, 0x00BB},
	{0xBC, 0x00BC}, {0xBD, 0x00BD}, {0xBE, 0x00BE}, {0xBF, 0x00BF},
	{0xC0, 0x00C0}, {0xC1, 0x00C1}, {0xC2, 0x00C2}, {0xC3, 0x00C3},
	{0xC4, 0x00C4}, {0xC5, 0x00C5}, {0xC6, 0x00C6}, {0xC7, 0x00C7},
	{0xC8, 0x00C8}, {0xC9, 0x00C9}, {0xCA, 0x00CA}, {0xCB, 0x00CB},
	{0xCC, 0x00CC}, {0xCD, 0x00CD}, {0xCE, 0x00CE}, {0xCF, 0x00CF},
	{0xD0, 0x00D0}, {0xD1, 0x00D1}, {0xD2, 0x00D2}, {0xD3, 0x00D3},
	{0xD4, 0x00D4}, {0xD5, 0x00D5}, {0xD6, 0x00D6}, {0xD7, 0x00D7},
	{0xD8, 0x00D8}, {0xD9, 0x00D9}, {0xDA, 0x00DA}, {0xDB, 0x00DB},
	{0xDC, 0x00DC}, {0xDD, 0x00DD}, {0xDE, 0x00DE}, {0xDF, 0x00DF},
	{0xE0, 0x00E0}, {0xE1, 0x00E1}, {0xE2, 0x00E2}, {0xE3, 0x00E3},
	{0xE4, 0x00E4}, {0xE5, 0x00E5}, {0xE6, 0x00E6}, {0xE7, 0x00E7},
	{0xE8, 0x00E8}, {0xE9, 0x00E9}, {0xEA, 0x00EA}, {0xEB, 0x00EB},
	{0xEC, 0x00EC}, {0xED, 0x00ED}, {0xEE, 0x00EE}, {0xEF, 0x00EF},
	{0xF0, 0x00F0}, {0xF1, 0x00F1}, {0xF2, 0x00F2}, {0xF3, 0x00F3},
	{0xF4, 0x00F4}, {0xF5, 0x00F5}, {0xF6, 0x00F6}, {0xF7, 0x00F7},
	{0xF8, 0x00F8}, {0xF9, 0x00F9}, {0xFA, 0x00FA}, {0xFB, 0x00FB},
	{0xFC, 0x00FC}, {0xFD, 0x00FD}, {0xFE, 0x00FE}, {0xFF, 0x00FF},
	{0x8C, 0x0152}, {0x9C, 0x0153}, {0x8A, 0x0160}, {0x9A, 0x0161},
	{0x9F, 0x0178}, {0x8E, 0x017D}, {0x9E, 0x017E}, {0x83, 0x0192},
	{0x88, 0x02C6}, {0x98, 0x02DC}, {0x96, 0x2013}, {0x97, 0x2014},
	{0x91, 0x2018}, {0x92, 0x2019}, {0x82, 0x201A}, {0x93, 0x201C},
	{0x94, 0x201D}, {0x84, 0x201E}, {0x86, 0x2020}, {0x87, 0x2021},
	{0x95, 0x2022}, {0x85, 0x2026}, {0x89, 0x2030}, {0x8B, 0x2039},
	{0x9B, 0x203A}, {0x80, 0x20AC}, {0x99, 0x2122}
};


codecvt_base::result cp1252cvt::do_in(mbstate_t&, const char* from,
  const char* from_end, const char*& from_next, wchar_t* to,
  wchar_t* to_limit, wchar_t*& to_next) const
{
	return ::do_in(from, from_end, from_next, to, to_limit, to_next, 0x80,
	  cp2ucs) ? codecvt_base::error : codecvt_base::ok;
}

codecvt_base::result cp1252cvt::do_out(mbstate_t&, const wchar_t* from,
  const wchar_t* from_end, const wchar_t*& from_next, char* to,
  char* to_limit, char*& to_next) const
{
	return ::do_out(from, from_end, from_next, to, to_limit, to_next, 0x80,
	  ucs2cp, sizeof(ucs2cp)) ? codecvt_base::error : codecvt_base::ok;
}

codecvt_base::result cp1252cvt::do_unshift(mbstate_t&, char* to, char*,
  char*& to_next) const
{
	to_next = to;

	return codecvt_base::noconv;
}
